<?php

namespace Ktnw\VodSupport\Utils;

use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Vod\Vod;
use AlibabaCloud\Kms\Kms;
use Illuminate\Support\Facades\Log;

/**
 * 阿里云视频点播相关接口
 * 创建API请求时，调用的方法名为Vod::v20170321()->${apiName}，其中${apiName}需要替换成要使用的点播API，但注意首字母需要调整为小写。
 */
class AliVod
{

    /**
     * 初始化
     * @param string $accessKeyId
     * @param string $accessKeySecret
     * @throws ClientException
     */
    public static function initVodClient(string $accessKeyId = '', string $accessKeySecret = '')
    {
        $accessKeyId     = empty($accessKeyId) ? self::getVodAccessKey() : $accessKeyId;
        $accessKeySecret = empty($accessKeySecret) ? self::getVodAccessKeySecret() : $accessKeySecret;
        $regionId        = self::getVodRegionId();
        AlibabaCloud::accessKeyClient($accessKeyId, $accessKeySecret)
            ->regionId($regionId)
            ->connectTimeout(1)
            ->timeout(3)
            ->asDefaultClient();
    }

    /**
     * 获取播放地址
     * @param string $videoId 视频id
     * @param int $previewTime 试看时间
     * @return array
     */
    public static function getPlayInfo(string $videoId, int $previewTime = 0): array
    {
        try {
            self::initVodClient();
            //设置播放配置
            $playConfig = ['PlayDomain' => self::getPlayDomain()];
            if ($previewTime > 0) {
                $playConfig['PreviewTime'] = (string)$previewTime;
            }
            $result        = Vod::v20170321()->getPlayInfo()
                ->withVideoId($videoId)// 指定接口参数
                ->withAuthTimeout(3600)
                ->withPlayConfig(json_encode($playConfig))
                ->format('JSON')// 指定返回格式
                ->request();      // 执行请求
            $videoBase     = $result->VideoBase;
            $CoverURL      = $videoBase->CoverURL; // 视频封面
            $Duration      = $videoBase->Duration; // 视频时长, 单位：秒
            $r['coverURL'] = $CoverURL;
            $r['duration'] = intval($Duration);
            $playInfo      = $result->PlayInfoList->PlayInfo;
            $playUrls      = [];
            foreach ($playInfo as $item) {
                $playUrls[$item->Definition] = $item->PlayURL;
            }
            $r['playUrls'] = $playUrls;
            return $r;
        } catch (\Exception $e) {
            Log::error($e);
            return [];
        }

    }

    /**
     * 获取播放凭证
     * @param string $videoId
     * @param int $previewTime 试看时间为0表示不是试看 大于0表示试看时间
     * @return array
     */
    public static function getPlayAuth(string $videoId, int $previewTime = 0): array
    {
        try {
            self::initVodClient();
            //设置播放配置
            $playConfig = ['PlayDomain' => self::getPlayDomain()];
            if ($previewTime > 0) {
                $playConfig['PreviewTime'] = $previewTime;
            }
            $result        = Vod::v20170321()->getVideoPlayAuth()
                ->withVideoId($videoId)// 指定接口参数
                ->withPlayConfig(json_encode($playConfig))
                ->withAuthInfoTimeout(3600)
                //->withAuthTimeout(3600 * 24)
                ->format('JSON')// 指定返回格式
                ->request();      // 执行请求
            $PlayAuth      = $result->PlayAuth;
            $CoverURL      = $result->VideoMeta->CoverURL ?? '';
            $Duration      = $result->VideoMeta->Duration ?? '';
            $r['coverURL'] = $CoverURL;
            $r['duration'] = intval($Duration);
            $r['playAuth'] = $PlayAuth;
            return $r;
        } catch (\Exception $e) {
            Log::error($e);
            return [];
        }
    }


    /**
     * 获取视频上传地址和凭证
     * @param UploadVideoQuery $query
     * @return array
     */
    public static function getUploadVideoAuth(UploadVideoQuery $query): array
    {
        try {
            self::initVodClient();
            //设置播放配置
            $workFlowId = self::getWorkFlowId();
            $result     = Vod::v20170321()->createUploadVideo()
                ->withFileName($query->getFileName())
                ->withTitle($query->getTitle())
                ->withCoverURL($query->getCoverUrl())
                ->withDescription($query->getDescription())
                ->withFileSize($query->getFileSize())
                ->withCateId($query->getCateId())
                //->withTemplateGroupId($query->getTemplateGroupId())
                ->withStorageLocation($query->getStorageLocation())
                ->withAppId($query->getAppId())
                ->withWorkflowId($workFlowId)
                ->format('JSON')// 指定返回格式
                ->request();      // 执行请求
            return $result->toArray();
        } catch (\Exception $e) {
            Log::error($e);
            return [];
        }
    }

    /**
     * 刷新视频上传凭证
     * @param $videoId
     * @return array
     */
    public static function refreshUploadVideo($videoId): array
    {
        try {
            self::initVodClient();
            $result = Vod::v20170321()->refreshUploadVideo()
                ->withVideoId($videoId)
                ->format('JSON')// 指定返回格式
                ->request();      // 执行请求
            return $result->toArray();
        } catch (\Exception $e) {
            Log::error($e);
            return [];
        }
    }


    /**
     * 删除视频
     * @param string $videoIds videoIds为传入的视频ID列表，多个用逗号分隔
     * @return array
     */
    public static function deleteVideo(string $videoIds): array
    {
        try {
            self::initVodClient();
            $result = Vod::v20170321()->deleteVideo()
                ->withVideoIds($videoIds)
                ->format('JSON')// 指定返回格式
                ->request();      // 执行请求
            return $result->toArray();
        } catch (\Exception $e) {
            Log::error($e);
            return [];
        }
    }

    /**
     * 获取视频信息
     * @param string $videoId 视频id
     * @return array
     */
    public static function getVideoInfo($videoId): array
    {
        try {
            self::initVodClient();
            $result = Vod::v20170321()->getVideoInfo()
                ->withVideoId($videoId)
                ->format('JSON')// 指定返回格式
                ->request();      // 执行请求
            return $result->toArray();
        } catch (\Exception $e) {
            Log::error($e);
            return [];
        }
    }

    /**
     * 生成HLS标准加密参数的可选配置，如不使用可忽略
     * 生成密钥API参考：https://help.aliyun.com/document_detail/28948.html
     */
    public static function buildEncryptConfig(): array
    {
        try {
            self::initVodClient();
            $keyId   = 'serviceKey'; // serviceKey 需提工单配置
            $keySpec = 'AES_128';
            $result  = Kms::v20160120()->generateDataKey()
                ->withKeyId($keyId)
                ->withKeySpec($keySpec)
                ->withAuthTimeout(3600 * 24)
                ->format('JSON')// 指定返回格式
                ->request();      // 执行请求
            dd($result);          // TODO
            # 解密接口地址，该参数需要将每次生成的密文秘钥与接口URL拼接生成，表示每个视频的解密的密文秘钥都不一样；注意您需要自己部署解密服务
            $encryptConfig["DecryptKeyUri"]  = "http://decrypt.demo.com/decrypt?Ciphertext=" + $result->getCiphertextBlob();
            $encryptConfig["KeyServiceType"] = "KMS";                       #秘钥服务的类型，目前只支持KMS
            $encryptConfig["CipherText"]     = $result->getCiphertextBlob();# Ciphertext作为解密接口的参数名称，可自定义，此处只作为参考
            return $encryptConfig;
        } catch (\Exception $e) {
            Log::error($e);
            return [];
        }
    }

    /**
     * 调用KMS decrypt接口解密，并将明文base64decode
     */
    public static function hlsDecrypt($ciphertextBlob)
    {
        try {
            self::initVodClient();
            $result = Kms::v20160120()->decrypt()
                ->withCiphertextBlob($ciphertextBlob)
                ->withAuthTimeout(3600 * 24)
                ->format('JSON')// 指定返回格式
                ->request();      // 执行请求
            dd($result);          // TODO
            $plaintext = $result->plaintext;
            //注意：需要base64 decode
            return base64_decode($plaintext);
        } catch (\Exception $e) {
            Log::error($e);
            return '';
        }
    }

    /**
     * 提交媒体处理作业
     * @param $videoId
     * @param $templateGroupId
     * @param $encryptConfig
     * @return array|string
     */
    public static function submitTranscodeJobs($videoId, $templateGroupId, $encryptConfig)
    {
        try {
            self::initVodClient();
            $params['keyId']   = 'serviceKey';
            $params['keySpec'] = 'AES_128';
            $result            = Vod::v20170321()->submitTranscodeJobs()
                ->withVideoId($videoId)
                ->withTemplateGroupId($templateGroupId)
                ->withEncryptConfig($encryptConfig)
                ->withAuthTimeout(3600 * 24)
                ->format('JSON')// 指定返回格式
                ->request();      // 执行请求
            dd($result);          // TODO
            return '';
        } catch (\Exception $e) {
            Log::error($e);
            return [];
        }
    }

    private static function getVodAccessKey()
    {
        return config("vodConfig.vod_access_key");
    }

    private static function getVodAccessKeySecret()
    {
        return config("vodConfig.vod_access_key_secret");
    }

    private static function getVodRegionId()
    {
        return config("vodConfig.vod_regionId");
    }

    private static function getPlayDomain()
    {
        return config("vodConfig.play_domain");
    }

    private static function getWorkFlowId()
    {
        return config("vodConfig.play_domain");
    }

    public static function getVodAccountId()
    {
        return config("vodConfig.vod_account_id");
    }

}